package in.abacritt.android.xclock;

import java.io.IOException;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.util.Calendar;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;

import android.util.Log;

public class OpenWeatherParser {
	LocationInfoWrapper currentLocation;

	public OpenWeatherParser(LocationInfoWrapper currentLocation) {
		this.currentLocation = currentLocation;
	}

	public WeatherInfo parseCurrentWeather() {
		String weatherXml = getWeatherXml();
		WeatherInfo weatherInfo = getWeatherFromXml(weatherXml);
		return weatherInfo;
	}

	private String getWeatherXml() {
		String xml = null;

		try {
			DefaultHttpClient httpClient = new DefaultHttpClient();
			HttpGet httpGet = new HttpGet(
					OpenWeatherConfig.getWeatherUrl(currentLocation));
			Log.d("WeatherUrl",
					OpenWeatherConfig.getWeatherUrl(currentLocation));
			httpGet.setHeader("X-API-Key", OpenWeatherConfig.API_KEY);

			HttpResponse httpResponse = httpClient.execute(httpGet);

			HttpEntity httpEntity = httpResponse.getEntity();
			xml = EntityUtils.toString(httpEntity);

		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

		return xml;
	}

	private WeatherInfo getWeatherFromXml(String xml) {
		String weatherConditionText;
		WeatherInfo weatherInfo = new WeatherInfo();

		try {
			XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
			// factory.setNamespaceAware(true);
			XmlPullParser parser = factory.newPullParser();

			parser.setInput(new StringReader(xml));
			int eventType = parser.getEventType();
			while (eventType != XmlPullParser.END_DOCUMENT) {
				String tagName = parser.getName();

				switch (eventType) {
				case XmlPullParser.START_TAG:
					if (tagName.equalsIgnoreCase("city")) {
						weatherInfo.locationName = parser.getAttributeValue(
								null, "name");
					} else if (tagName.equalsIgnoreCase("temperature")) {
						weatherInfo.temperature = parser.getAttributeValue(
								null, "value");
						weatherInfo.lowTemp = parser.getAttributeValue(null,
								"min");
						weatherInfo.highTemp = parser.getAttributeValue(null,
								"max");
						weatherInfo.tempUnit = parser.getAttributeValue(null,
								"unit");
					} else if (tagName.equalsIgnoreCase("humidity")) {
						weatherInfo.humidity = parser.getAttributeValue(null,
								"value");
					} else if (tagName.equalsIgnoreCase("weather")) {
						weatherInfo.condition = Integer.parseInt(parser
								.getAttributeValue(null, "number"));
						weatherConditionText = parser.getAttributeValue(null,
								"value");
						weatherInfo.conditionText = weatherConditionText
								.toUpperCase().charAt(0)
								+ weatherConditionText.substring(1);

					}

					break;
				default:
					break;
				}
				eventType = parser.next();
			}

		} catch (XmlPullParserException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

		weatherInfo.iconName = getWeatherIconName(weatherInfo.condition);
		return weatherInfo;
	}

	private String getWeatherIconName(int condition) {

		String iconName = "weather_";
		Calendar currentTime = Calendar.getInstance();

		if (condition >= 200 && condition <= 232) {
			// Thunderstorm
			iconName += "thunderstorm";
		} else if (condition >= 300 && condition <= 321) {
			// Drizzle
			iconName += "drizzle";
		} else if (condition >= 500 && condition <= 531) {
			// Rain
			if (condition == 511) {
				// snow rain
				iconName += "snow";
			} else {
				iconName += "rain";
			}
		} else if (condition >= 600 && condition <= 622) {
			// Snow
			iconName += "snow";
		} else if (condition == 701 || condition == 711 | condition == 721
				|| condition == 741) {
			// Foggy/Haze
			iconName += "foggy";
		} else if (condition == 731 || condition == 751 | condition == 761) {
			// Foggy/Haze
			iconName += "dust";
		} else if (condition >= 800 && condition <= 804) {
			if (condition == 800) {
				// clear
				if (currentTime.get(Calendar.HOUR_OF_DAY) < 18) {
					iconName += "clear";
				} else {
					iconName += "clear_night";
				}
			} else {
				// Cloudy
				if (currentTime.get(Calendar.HOUR_OF_DAY) < 18) {
					iconName += "cloudly";
				} else {
					iconName += "cloudly_night";
				}
			}
		} else if (condition == 903) {
			// cold
			iconName += "cold";
		} else if (condition == 904) {
			// hot
			iconName += "clear";
		} else if (condition == 905) {
			// windy
			iconName += "windy";
		} else if (condition == 906) {
			// hail
			iconName += "hail";
		} else {
			if (currentTime.get(Calendar.HOUR_OF_DAY) < 18) {
				iconName += "cloudly";
			} else {
				iconName += "cloudly_night";
			}
		}

		Log.d("weathericon", iconName);
		return iconName;
	}
}
